using GameConfig.item;
using GameLogic;
using System;
using System.Collections.Generic;
using TEngine;
using UnityEngine;
using UnityEngine.SceneManagement;
using UnityEngine.Tilemaps;

public class GridMapManager : SingletonBehaviour<GridMapManager>
{
    [Header("种地瓦片切换信息")]
    private Tilemap digTilemap;
    private Tilemap waterTilemap;

    [Header("地图信息")]
    public List<MapData_SO> mapDataList;

    private Season currentSeason;


    //场景名字+坐标和对应的瓦片信息
    private Dictionary<string, TileDetails> tileDetailsDict = new Dictionary<string, TileDetails>();

    //场景名字+坐标和对应的土地信息
    private Dictionary<string, Ground> groundsDict = new Dictionary<string, Ground>();

    //场景是否第一次加载
    private Dictionary<string, bool> firstLoadDict = new Dictionary<string, bool>();

    private Grid currentGrid;

    private void OnEnable()
    {
        GameEvent.AddEventListener<Vector3, ItemTb>(ILoginUI_Event.ExecuteActionAfterAnimation, OnExecuteActionAfterAnimation);
        GameEvent.AddEventListener(ILoginUI_Event.AfterSceneLoadedEvent, OnAfterSceneLoadedEvent);
        GameEvent.AddEventListener(ILoginUI_Event.OnTimerChange, OnTimerChange);
        GameEvent.AddEventListener(ILoginUI_Event.OnDayChange, OnDayChange);
    }

    private void OnDayChange()
    {

    }

    private void OnTimerChange()
    {
    }

    private void OnDisable()
    {
    }


    public void Init()
    {

    }

    private void OnAfterSceneLoadedEvent()
    {
        currentGrid = FindObjectOfType<Grid>();
        if (currentGrid == null) return;
        digTilemap = GameObject.FindWithTag("Dig").GetComponent<Tilemap>();
        waterTilemap = GameObject.FindWithTag("Water").GetComponent<Tilemap>();
    }

    /// <summary>
    /// 根据地图信息生成字典
    /// </summary>
    /// <param name="mapData">地图信息</param>
    public void InitTileDetailsDict(string mapScene, MapDataJson mapData)
    {
        foreach (TileProperty tileProperty in mapData.tileProperties)
        {
            TileDetails tileDetails = new TileDetails
            {
                girdX = tileProperty.tileCoordinate.x,
                gridY = tileProperty.tileCoordinate.y
            };

            //字典的Key
            string key = tileDetails.girdX + "x" + tileDetails.gridY + "y" + mapScene;

            if (GetTileDetails(key) != null)
            {
                tileDetails = GetTileDetails(key);
            }

            switch (tileProperty.gridType)
            {
                case GridType.Diggable:
                    tileDetails.canDig = tileProperty.boolTypeValue;
                    break;
                case GridType.DropItem:
                    tileDetails.canDropItem = tileProperty.boolTypeValue;
                    break;
                case GridType.PlaceFurniture:
                    tileDetails.canPlaceFurniture = tileProperty.boolTypeValue;
                    break;
                case GridType.NPCObstacle:
                    tileDetails.isNPCObstacle = tileProperty.boolTypeValue;
                    break;
            }

            if (GetTileDetails(key) != null)
                tileDetailsDict[key] = tileDetails;
            else
                tileDetailsDict.Add(key, tileDetails);
        }
    }


    /// <summary>
    /// 根据key返回瓦片信息
    /// </summary>
    /// <param name="key">x+y+地图名字</param>
    /// <returns></returns>
    public TileDetails GetTileDetails(string key)
    {
        if (tileDetailsDict.ContainsKey(key))
        {
            return tileDetailsDict[key];
        }
        return null;
    }

    /// <summary>
    /// 根据鼠标网格坐标返回瓦片信息
    /// </summary>
    /// <param name="mouseGridPos">鼠标网格坐标</param>
    /// <returns></returns>
    public TileDetails GetTileDetailsOnMousePosition(Vector3Int mouseGridPos)
    {
        string key = mouseGridPos.x + "x" + mouseGridPos.y + "y" + SceneManager.GetActiveScene().name;
        return GetTileDetails(key);
    }


    /// <summary>
    /// 执行实际工具或物品功能
    /// </summary>
    /// <param name="mouseWorldPos">鼠标坐标</param>
    /// <param name="itemDetails">物品信息</param>
    private void OnExecuteActionAfterAnimation(Vector3 mouseWorldPos, ItemTb itemDetails)
    {
        var mouseGridPos = currentGrid.WorldToCell(mouseWorldPos);
        var currentTile = GetTileDetailsOnMousePosition(mouseGridPos);
        string key = mouseGridPos.x + "x" + mouseGridPos.y + "y" + SceneManager.GetActiveScene().name;
        if (currentTile != null)
        {
            //Crop currentCrop = GetCropObject(mouseWorldPos);

            //WORKFLOW:物品使用实际功能
            switch (itemDetails.ItemType)
            {
                case GameConfig.item.ItemType.Seed:
                    GameEvent.Get<ILoginUI>().CallPlantSeedEvent(itemDetails.ItemID, currentTile);
                    //EventHandler.CallPlantSeedEvent(itemDetails.itemID, currentTile);
                    //EventHandler.CallDropItemEvent(itemDetails.itemID, mouseWorldPos, itemDetails.itemType);
                    break;
                case GameConfig.item.ItemType.Commodity:
                    //EventHandler.CallDropItemEvent(itemDetails.itemID, mouseWorldPos, itemDetails.itemType);
                    break;
                case GameConfig.item.ItemType.HoeTool:
                    SetDigGround(currentTile);
                    Ground ground = new Ground();
                    ground.Init(currentTile);
                    ground.OnDigInit();
                    
                    groundsDict[key] = ground;
                    //音效
                    //EventHandler.CallPlaySoundEvent(SoundName.Hoe);
                    break;
                case GameConfig.item.ItemType.WaterTool:
                    SetWaterGround(currentTile);
                    if(groundsDict.TryGetValue(key,out Ground target))
                    {
                        target.AddWetness(itemDetails.QualityValue); // 浇水
                    }
                    //currentTile.daysSinceWatered = 0;
                    //音效
                    //EventHandler.CallPlaySoundEvent(SoundName.Water);
                    break;
                case GameConfig.item.ItemType.BreakTool:
                case GameConfig.item.ItemType.ChopTool:
                    //执行收割方法
                    //currentCrop?.ProcessToolAction(itemDetails, currentCrop.tileDetails);
                    break;
                case GameConfig.item.ItemType.CollectTool:
                    //Crop currentCrop = GetCropObject(mouseWorldPos);
                    //执行收割方法
                    //currentCrop.ProcessToolAction(itemDetails, currentTile);
                    //EventHandler.CallPlaySoundEvent(SoundName.Basket);
                    break;
                case GameConfig.item.ItemType.ReapTool:
                    var reapCount = 0;
                    //for (int i = 0; i < itemsInRadius.Count; i++)
                    //{
                    //    //EventHandler.CallParticleEffectEvent(ParticleEffectType.ReapableScenery, itemsInRadius[i].transform.position + Vector3.up);
                    //    itemsInRadius[i].SpawnHarvestItems();
                    //    Destroy(itemsInRadius[i].gameObject);
                    //    reapCount++;
                    //    if (reapCount >= Settings.reapAmount)
                    //        break;
                    //}
                    //EventHandler.CallPlaySoundEvent(SoundName.Reap);
                    break;

                case GameConfig.item.ItemType.Furniture:
                    //在地图上生成物品 ItemManager
                    //移除当前物品（图纸）InventoryManager
                    //移除资源物品 InventoryManger
                    //EventHandler.CallBuildFurnitureEvent(itemDetails.itemID, mouseWorldPos);
                    break;
            }

            UpdateTileDetails(currentTile);
        }
    }

    /// <summary>
    /// 通过物理方法判断鼠标点击位置的农作物
    /// </summary>
    /// <param name="mouseWorldPos">鼠标坐标</param>
    /// <returns></returns>
    //public Crop GetCropObject(Vector3 mouseWorldPos)
    //{
    //    Collider2D[] colliders = Physics2D.OverlapPointAll(mouseWorldPos);

    //    Crop currentCrop = null;

    //    for (int i = 0; i < colliders.Length; i++)
    //    {
    //        if (colliders[i].GetComponent<Crop>())
    //            currentCrop = colliders[i].GetComponent<Crop>();
    //    }
    //    return currentCrop;
    //}


    /// <summary>
    /// 返回工具范围内的杂草
    /// </summary>
    /// <param name="tool">物品信息</param>
    /// <returns></returns>
    //public bool HaveReapableItemsInRadius(Vector3 mouseWorldPos, ItemDetails tool)
    //{
    //    itemsInRadius = new List<ReapItem>();

    //    Collider2D[] colliders = new Collider2D[20];

    //    Physics2D.OverlapCircleNonAlloc(mouseWorldPos, tool.itemUseRadius, colliders);

    //    if (colliders.Length > 0)
    //    {
    //        for (int i = 0; i < colliders.Length; i++)
    //        {
    //            if (colliders[i] != null)
    //            {
    //                if (colliders[i].GetComponent<ReapItem>())
    //                {
    //                    var item = colliders[i].GetComponent<ReapItem>();
    //                    itemsInRadius.Add(item);
    //                }
    //            }
    //        }
    //    }
    //    return itemsInRadius.Count > 0;
    //}

    /// <summary>
    /// 显示挖坑瓦片
    /// </summary>
    /// <param name="tile"></param>
    private void SetDigGround(TileDetails tile)
    {
        Vector3Int pos = new Vector3Int(tile.girdX, tile.gridY, 0);
        if (digTilemap != null)
            digTilemap.SetTile(pos, ScenePrefabGet.Instance.digTile);
    }

    /// <summary>
    /// 显示浇水瓦片
    /// </summary>
    /// <param name="tile"></param>
    private void SetWaterGround(TileDetails tile)
    {
        Vector3Int pos = new Vector3Int(tile.girdX, tile.gridY, 0);
        if (waterTilemap != null)
            waterTilemap.SetTile(pos, ScenePrefabGet.Instance.waterTile);
    }

    /// <summary>
    /// 更新瓦片信息
    /// </summary>
    /// <param name="tileDetails"></param>
    public void UpdateTileDetails(TileDetails tileDetails)
    {
        string key = tileDetails.girdX + "x" + tileDetails.gridY + "y" + SceneManager.GetActiveScene().name;
        if (tileDetailsDict.ContainsKey(key))
        {
            tileDetailsDict[key] = tileDetails;
        }
        else
        {
            tileDetailsDict.Add(key, tileDetails);
        }
    }


    /// <summary>
    /// 刷新当前地图
    /// </summary>
    private void RefreshMap()
    {
        if (digTilemap != null)
            digTilemap.ClearAllTiles();
        if (waterTilemap != null)
            waterTilemap.ClearAllTiles();

        //foreach (var crop in FindObjectsOfType<Crop>())
        //{
        //    Destroy(crop.gameObject);
        //}

        DisplayMap(SceneManager.GetActiveScene().name);
    }


    /// <summary>
    /// 显示地图瓦片
    /// </summary>
    /// <param name="sceneName">场景名字</param>
    private void DisplayMap(string sceneName)
    {
        foreach (var tile in tileDetailsDict)
        {
            var key = tile.Key;
            var tileDetails = tile.Value;

            if (key.Contains(sceneName))
            {
                if (tileDetails.sinceDuged > -1)
                    SetDigGround(tileDetails);
                if (tileDetails.Wetness > -1)
                    SetWaterGround(tileDetails);
                if (tileDetails.seedItemID > -1)
                    GameEvent.Get<ILoginUI>().CallPlantSeedEvent(tileDetails.seedItemID, tileDetails);
            }
        }
    }


    /// <summary>
    /// 根据场景名字构建网格范围，输出范围和原点
    /// </summary>
    /// <param name="sceneName">场景名字</param>
    /// <param name="gridDimensions">网格范围</param>
    /// <param name="gridOrigin">网格原点</param>
    /// <returns>是否有当前场景的信息</returns>
    public bool GetGridDimensions(string sceneName, out Vector2Int gridDimensions, out Vector2Int gridOrigin)
    {
        gridDimensions = Vector2Int.zero;
        gridOrigin = Vector2Int.zero;

        foreach (var mapData in mapDataList)
        {
            if (mapData.sceneName == sceneName)
            {
                gridDimensions.x = mapData.gridWidth;
                gridDimensions.y = mapData.gridHeight;

                gridOrigin.x = mapData.originX;
                gridOrigin.y = mapData.originY;

                return true;
            }
        }
        return false;
    }
}